---
type: integration
title: '@astrojs/react'
description: '@astrojs/react 프레임워크 통합을 사용하여 Astro 프로젝트에서 컴포넌트 지원을 확장하는 방법을 알아보세요.'
sidebar:
  label: React
githubIntegrationURL: 'https://github.com/withastro/astro/tree/main/packages/integrations/react/'
category: renderer
i18nReady: true
---
import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro'
import Since from '~/components/Since.astro';

이 **[Astro 통합][astro-integration]을** 통해 [React](https://react.dev/) 컴포넌트에 대한 렌더링 및 클라이언트 측 하이드레이션이 가능해졌습니다.

## 설치

Astro에는 공식 통합 설정을 자동화하는 `astro add` 명령이 포함되어 있습니다. 원하는 경우 대신 [통합을 수동으로 설치](#수동-설치)할 수 있습니다.

`@astrojs/react`를 설치하려면 프로젝트 디렉터리에서 다음을 실행하고 프롬프트를 따르세요.

<PackageManagerTabs>
  <Fragment slot="npm">
  ```sh
  npx astro add react
  ```
  </Fragment>
  <Fragment slot="pnpm">
  ```sh
  pnpm astro add react
  ```
  </Fragment>
  <Fragment slot="yarn">
  ```sh
  yarn astro add react
  ```
  </Fragment>
</PackageManagerTabs>

문제가 발생하면 [GitHub에서 언제든지 보고](https://github.com/withastro/astro/issues)하고 아래 수동 설치 단계를 시도해 보세요.

### 수동 설치

먼저 `@astrojs/react` 패키지를 설치하세요.

<PackageManagerTabs>
  <Fragment slot="npm">
  ```sh
  npm install @astrojs/react
  ```
  </Fragment>
  <Fragment slot="pnpm">
  ```sh
  pnpm add @astrojs/react
  ```
  </Fragment>
  <Fragment slot="yarn">
  ```sh
  yarn add @astrojs/react
  ```
  </Fragment>
</PackageManagerTabs>

대부분의 패키지 관리자는 관련 피어 종속성도 설치합니다. Astro를 시작할 때 `Cannot find package 'react'` (또는 이와 유사한) 경고가 표시되면 `react`와 `react-dom` 및 타입 정의를 설치해야 합니다.

<PackageManagerTabs>
  <Fragment slot="npm">
  ```sh
  npm install react react-dom @types/react @types/react-dom
  ```
  </Fragment>
  <Fragment slot="pnpm">
  ```sh
  pnpm add react react-dom @types/react @types/react-dom
  ```
  </Fragment>
  <Fragment slot="yarn">
  ```sh
  yarn add react react-dom @types/react @types/react-dom
  ```
  </Fragment>
</PackageManagerTabs>

그런 다음 `integrations` 속성을 사용하여 `astro.config.*` 파일에 통합을 적용합니다.

```js ins="react()" ins={2} title="astro.config.mjs"
import { defineConfig } from 'astro/config';
import react from '@astrojs/react';

export default defineConfig({
  // ...
  integrations: [react()],
});
```

그리고 `tsconfig.json` 파일에 다음 코드를 추가하세요.

```json title="tsconfig.json" ins={5-8}
{
  "extends": "astro/tsconfigs/strict",
  "include": [".astro/types.d.ts", "**/*"],
  "exclude": ["dist"],
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "react"
  }
}
```

## 시작하기

Astro에서 첫 번째 React 컴포넌트를 사용하려면 [UI 프레임워크 문서][astro-ui-frameworks]로 이동하세요. 다음을 탐색하게 됩니다.

* 📦 프레임워크 컴포넌트가 로드되는 방식,
* 💧 클라이언트 측 하이드레이션 옵션
* 🤝 프레임워크를 함께 혼합하고 중첩할 수 있는 기회

## `useActionState()`를 사용하여 액션 통합하기

`@astrojs/react` 통합은 [Astro 액션][astro-actions]과 함께 사용할 수 있는 두 가지 함수인 `withState()`와 `getActionState()`를 제공합니다.

이 함수들은 [React의 useActionState() 훅](https://ko.react.dev/reference/react/useActionState)과 함께 사용되어, 양식을 제출하여 액션을 트리거할 때 클라이언트 측 상태를 읽고 업데이트합니다.

### `withState()`

<p>

**타입:** `(action: FormFn<T>) => (state: T, formData: FormData) => FormFn<T>`<br />
<Since v="4.4.0" pkg="@astrojs/react" />
</p>

`withState()`와 실행하려는 액션을 React의 `useActionState()` 훅에 양식 액션 함수로 전달할 수 있습니다. 다음은 카운터를 증가시키는 `like` 액션과 함께 초기 상태인 좋아요 `0`개를 전달하는 예시입니다.

```jsx title="Like.tsx" ins={2,7} "useActionState"
import { actions } from 'astro:actions';
import { withState } from '@astrojs/react/actions';
import { useActionState } from "react";

export function Like({ postId }: { postId: string }) {
  const [state, action, pending] = useActionState(
    withState(actions.like),
    { data: 0, error: undefined }, // 좋아요 수와 오류의 초깃값
  );

  return (
    <form action={action}>
      <input type="hidden" name="postId" value={postId} />
      <button disabled={pending}>{state.data} ❤️</button>
    </form>
  );
}
```

`withState()` 함수는 액션의 타입을 React의 기대값과 일치시킵니다. 이를 통해 점진적 개선에 사용되는 메타데이터를 보존하여, 사용자의 기기에서 JavaScript가 비활성화된 경우에도 작동할 수 있도록 합니다.

### `getActionState()`

<p>

**타입:** `(context: ActionAPIContext) => Promise<T>`<br />
<Since v="4.4.0" pkg="@astrojs/react" />
</p>

액션의 `handler`에서 `getActionState()`를 사용하여 서버에서 `useActionState()`로 저장한 상태에 접근할 수 있습니다. 이 함수는 [Astro API 컨텍스트](/ko/reference/api-reference/#컨텍스트-객체)를 인수로 받으며, 선택적으로 결과에 타입을 적용할 수 있습니다.

다음은 카운터에서 숫자 타입의 현재 좋아요 수를 가져와 이를 증가시키는 `like` 액션을 생성하는 예시입니다.

```ts title="actions.ts" ins={3,11}
import { defineAction, type SafeResult } from 'astro:actions';
import { z } from 'astro:schema';
import { getActionState } from '@astrojs/react/actions';

export const server = {
  like: defineAction({
    input: z.object({
      postId: z.string(),
    }),
    handler: async ({ postId }, ctx) => {
      const { data: currentLikes = 0, error } = await getActionState<SafeResult<any, number>>(ctx);
      
      // 오류 처리
      if (error) throw error;

      // 데이터베이스 업데이트
      return currentLikes + 1;
    },
  })
};
```

## 옵션

### 여러 JSX 프레임워크 결합

동일한 프로젝트에서 여러 JSX 프레임워크 (React, Preact, Solid)를 사용하는 경우 Astro는 각 컴포넌트에 어떤 JSX 프레임워크별 변환을 사용해야 하는지 결정해야 합니다. 프로젝트에 하나의 JSX 프레임워크 통합만 추가한 경우 추가 구성이 필요하지 않습니다.

어떤 파일이 어떤 프레임워크에 속하는지 지정하려면 `include` (필수) 및 `exclude` (선택 사항) 구성 옵션을 사용하세요. 사용 중인 각 프레임워크에 `포함`할 파일 및/또는 폴더 배열을 제공하세요. 와일드카드를 사용하여 여러 파일 경로를 포함할 수 있습니다.

포함을 더 쉽게 지정할 수 있도록 공통 프레임워크 컴포넌트를 동일한 폴더 (예: `/components/react/` 및 `/components/solid/`)에 배치하는 것이 좋지만 필수는 아닙니다.

```js title="astro.config.mjs"
import { defineConfig } from 'astro/config';
import preact from '@astrojs/preact';
import react from '@astrojs/react';
import svelte from '@astrojs/svelte';
import vue from '@astrojs/vue';
import solid from '@astrojs/solid-js';

export default defineConfig({
  // 다양한 종류의 컴포넌트를 지원하기 위해 많은 프레임워크를 활성화합니다.
  // 단일 JSX 프레임워크만 사용하는 경우 `include`가 필요하지 않습니다!
  integrations: [
    preact({
      include: ['**/preact/*'],
    }),
    react({
      include: ['**/react/*'],
    }),
    solid({
      include: ['**/solid/*'],
    }),
  ],
});
```

### Children 구문 분석

Astro 컴포넌트에서 React 컴포넌트로 전달된 하위 요소는 React 노드가 아닌 일반 문자열로 구문 분석됩니다.

예를 들어 아래 `<ReactComponent />`는 단일 하위 요소만 수신합니다.

```astro
---
import ReactComponent from './ReactComponent';
---

<ReactComponent>
  <div>one</div>
  <div>two</div>
</ReactComponent>
```

예를 들어 특정 요소를 다른 위치에 배치할 수 있도록 하나 이상의 하위 요소가 전달될 것으로 *예상*하는 라이브러리를 사용하는 경우 이것이 차단 요인이 될 수 있습니다.

실험적 플래그 `experimentalReactChildren`을 설정하여 React의 자식 요소로 항상 React 가상 DOM 노드를 전달하도록 Astro에게 지시할 수 있습니다. 이는 약간의 런타임 비용이 있지만 호환성에 도움이 될 수 있습니다.

React 통합 구성에서 이 옵션을 활성화할 수 있습니다.

```js title="astro.config.mjs" ins={8}
import { defineConfig } from 'astro/config';
import react from '@astrojs/react';

export default defineConfig({
  // ...
  integrations: [
    react({
      experimentalReactChildren: true,
    }),
  ],
});
```

### 스트리밍 비활성화 (실험적)

Astro는 기본적으로 React 컴포넌트의 출력을 스트리밍합니다. 그러나 `experimentalDisableStreaming` 옵션을 활성화하여 이 동작을 비활성화할 수 있습니다. 이 옵션은 일부 CSS-in-JS 솔루션처럼 스트리밍과 잘 작동하지 않는 라이브러리를 지원할 때 특히 유용합니다.

프로젝트의 모든 React 컴포넌트에 대해 스트리밍을 비활성화하려면 `@astrojs/react`에서 `experimentalDisableStreaming: true`를 구성하세요:

```js title="astro.config.mjs" ins={8}
import { defineConfig } from 'astro/config';
import react from '@astrojs/react';

export default defineConfig({
  // ...
  integrations: [
    react({
      experimentalDisableStreaming: true,
    })
  ]
});
```

[astro-integration]: /ko/guides/integrations-guide/

[astro-ui-frameworks]: /ko/guides/framework-components/#프레임워크-컴포넌트-사용

[astro-actions]: /ko/guides/actions/
